package com.cqjtu.store.user.service.impl;

import com.cqjtu.store.common.*;
import com.cqjtu.store.user.mapper.UserMapper;
import com.cqjtu.store.user.pojo.dto.*;
import com.cqjtu.store.user.pojo.entity.User;
import com.cqjtu.store.user.pojo.vo.UserLoginVO;
import com.cqjtu.store.user.pojo.vo.UserShowVO;
import com.cqjtu.store.user.pojo.vo.UserVO;
import com.cqjtu.store.user.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Base64;
import java.util.UUID;

/**
 * @ProjectName: cqjtu-store
 * @Titile: UserServiceImpl
 * @Author: Lucky
 * @Description: 用户业务实现类
 */
@Service
@Transactional //开启事务
@Slf4j
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;

    @Override
    public void register(UserRegDTO userRegDTO) {
        // todo 判断 密码和重复密码是否一致
        String existPassword = userRegDTO.getPassword();
        String existRePassword = userRegDTO.getRePassword();
        if (!existPassword.equals(existRePassword)) {
            System.out.println("密码不一致");
            throw new ServiceException(ServiceCode.ERR_EXISTS, "两次输入密码不一致，请重新输入！");
        }
        User existsUser = userMapper.getUserByName(userRegDTO.getUsername());
        if (existsUser != null) {
            System.out.println("已经存在");
            throw new ServiceException(ServiceCode.ERR_EXISTS, "该用户已经存在,不能重复注册.");
        }
        User user = new User();
        user.setUsername(userRegDTO.getUsername());
        String salt = UUID.randomUUID().toString().replace("-", "");
        user.setSalt(salt);
        String password = MD5Utils.enctype(userRegDTO.getPassword(), salt, Constants.HASH_TIME);
        user.setPassword(password);
        //是否被删除
        user.setIsDelete(Constants.IS_NOT_DELETE);
        user.setCreatedUser(userRegDTO.getUsername());
        int result = userMapper.insert(user);
        if (result != 1) {
            throw new ServiceException(ServiceCode.ERR_SAVE_FAILED, "注册用户失败");
        }
    }


    @Override
    public R<UserLoginVO> login(UserLoginDTO userLoginDTO) {
        //根据用户名去查询用户
        User user = userMapper.getUserByName(userLoginDTO.getUsername());
        if (user == null) {
            return R.fail(ServiceCode.ERR_NOT_FOUND, "用户不存在");
        }
        //对密码进行加密后才判断
        String password = MD5Utils.enctype(userLoginDTO.getPassword(), user.getSalt(), Constants.HASH_TIME);
        if (!password.equals(user.getPassword())) {
            return R.fail(ServiceCode.ERR_PWD, "密码错误");
        }
        //从user中取出需要的数据：id,username,封装
        UserLoginVO userLoginVO = new UserLoginVO();
        if (user.getIsDelete() == 1) {
            return R.fail(ServiceCode.ERR_BAD_REQUEST, "该账号已被禁用");
        }
        userLoginVO.setId(user.getId());
        userLoginVO.setUsername(user.getUsername());

        //生成token
        String token = JwtUtils.generateToken(userLoginVO);
        userLoginVO.setToken(token);
        return R.ok(userLoginVO);
    }


    /**
     * 修改密码的业务
     *
     * @param pwdUpdateDTO
     */
    @Override
    public void updatePwd(PwdUpdateDTO pwdUpdateDTO, UserLoginVO userLoginVO) {
        String existPassword = pwdUpdateDTO.getNewPwd();
        String existRePassword = pwdUpdateDTO.getReNewPwd();
        if (!existPassword.equals(existRePassword)) {
            System.out.println("密码不一致");
            throw new ServiceException(ServiceCode.ERR_EXISTS, "两次输入密码不一致，请重新输入！");
        }
        //判断用户是否存在
        User user = userMapper.getUserByName(userLoginVO.getUsername());
        if (user == null) {
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, "用户不存在");
        }
        // 判断密码是否正确
        String oldPassword = MD5Utils.enctype(pwdUpdateDTO.getOldPwd(), user.getSalt(), Constants.HASH_TIME);
        if (!oldPassword.equals(user.getPassword())) {
            throw new ServiceException(ServiceCode.ERR_PWD, "原密码错误");
        }
        //修改密码
        //获取salt
        String salt = UUID.randomUUID().toString().replace("-", "");
        //加密
        String newPassword = MD5Utils.enctype(pwdUpdateDTO.getNewPwd(), salt, Constants.HASH_TIME);
        //构造一个用户对象
        User updateUser = new User();
        updateUser.setId(userLoginVO.getId());
        updateUser.setPassword(newPassword);
        updateUser.setSalt(salt);
        updateUser.setModifiedUser(userLoginVO.getUsername());
        int result = userMapper.updatePwd(updateUser);
        if (result != 1) {
            throw new ServiceException(ServiceCode.ERR_SAVE_FAILED, "修改密码失败");
        }
    }

    /**
     * 查询用户
     *
     * @param userLoginVO
     * @return
     */
    @Override
    public UserVO getUser(UserLoginVO userLoginVO) {
        User user = userMapper.getUserByName(userLoginVO.getUsername());
        if (user == null) {
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, "用户不存在");
        }
        //封装查询的用户信息
        UserVO userVO = new UserVO();
        userVO.setUsername(user.getUsername());
        userVO.setPhone(user.getPhone());
        userVO.setEmail(user.getEmail());
        userVO.setAvatar(user.getAvatar());
        userVO.setGender(user.getGender());
        return userVO;
    }

    /**
     * 修改用户信息
     *
     * @param userUpdateDTO 修改的信息
     * @param userLoginVO   修改人
     */
    @Override
    public void updateUser(UserUpdateDTO userUpdateDTO, UserLoginVO userLoginVO) {
        if (!userUpdateDTO.getUsername().equals(userLoginVO.getUsername())) {
            throw new ServiceException(ServiceCode.ERR_FORBIDDEN, "该用户禁止修改");
        }
        User user = new User();
        user.setUsername(userLoginVO.getUsername());
        user.setPhone(userUpdateDTO.getPhone());
        user.setEmail(userUpdateDTO.getEmail());
        user.setGender(userUpdateDTO.getGender());
        user.setModifiedUser(userLoginVO.getUsername());
        int result = userMapper.updateUser(user);
        if (result != 1) {
            throw new ServiceException(ServiceCode.ERR_SAVE_FAILED, "用户修改失败");
        }
    }

    /**
     * 上传头像
     *
     * @param avatar      头像
     * @param userLoginVO 上传头像的那个人
     */

    @Override
    public void upload(MultipartFile avatar, UserLoginVO userLoginVO) {

        // Convert avatar file to Base64 encoding
        String base64Avatar = convertFileToBase64(avatar);

        // 将Base64编码的头像传递给前端
        User user = new User();
        user.setUsername(userLoginVO.getUsername());
        System.out.println(base64Avatar);
        user.setAvatar(base64Avatar);
        user.setModifiedUser(userLoginVO.getUsername());

        int result = userMapper.saveAvatar(user);
        if (result != 1) {
            throw new ServiceException(ServiceCode.ERR_SAVE_FAILED, "头像路径保存数据库失败");
        }
    }

    @Override
    public String convertFileToBase64(MultipartFile file) {
        try {
            byte[] fileContent = file.getBytes();
            String base64Encoded = Base64.getEncoder().encodeToString(fileContent);
            return "data:" + file.getContentType() + ";base64," + base64Encoded;
        } catch (IOException e) {
            throw new ServiceException(ServiceCode.ERR_CONVERT_TO_BASE64, "文件转换为Base64编码失败");
        }
    }
    public  static void test(){

    }

    @Override
    public void addUser(UserUpdateDTO userUpdateDTO) {
        User existsUser = userMapper.getUserByName(userUpdateDTO.getUsername());
        if (existsUser != null) {
            System.out.println("已经存在");
            throw new ServiceException(ServiceCode.ERR_EXISTS, "该用户已经存在,不能重复注册.");
        }
        User user = new User();
        user.setUsername(userUpdateDTO.getUsername());
        user.setPhone(userUpdateDTO.getPhone());
        user.setEmail(userUpdateDTO.getEmail());
//        user.setGender(userUpdateDTO.getGender());
        String salt = UUID.randomUUID().toString().replace("-", "");
        user.setSalt(salt);
        String password = MD5Utils.enctype(Constants.DEFAULT_PASSWORD, salt, Constants.HASH_TIME);
        user.setPassword(password);
        //是否被删除
        user.setIsDelete(Constants.IS_NOT_DELETE);
        user.setCreatedUser(userUpdateDTO.getUsername());
        int result = userMapper.addUser(user);
        if (result != 1) {
            throw new ServiceException(ServiceCode.ERR_SAVE_FAILED, "新增用户失败");
        }

    }

    @Override
    public void stopUser(Integer id) {
        //判断用户id是否存在于数据库
        User user = userMapper.getById(id);
        if (user == null) {
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, "该用户不存在");
        }
        //设置用户状态停用
        user.setIsDelete(Constants.NOT_DEFAULT_USER);
        int result = userMapper.stopOrStartUser(user);
        if (result != 1) {
            throw new ServiceException(ServiceCode.ERR_SAVE_FAILED, "禁用用户失败");
        }

    }

    @Override
    public void startUser(Integer id) {
        //判断用户id是否存在于数据库
        User user = userMapper.getById(id);
        if (user == null) {
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, "该用户不存在");
        }
        //设置用户状态启用
        user.setIsDelete(Constants.DEFAULT_USER);
        int result = userMapper.stopOrStartUser(user);
        if (result != 1) {
            throw new ServiceException(ServiceCode.ERR_SAVE_FAILED, "启用用户失败");
        }

    }

    @Override
    public void resetUser(Integer id) {
        //判断用户id是否存在于数据库
        User user = userMapper.getById(id);
        if (user == null) {
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, "该用户不存在");
        }
        String salt = UUID.randomUUID().toString().replace("-", "");
        user.setSalt(salt);
        String password = MD5Utils.enctype(Constants.DEFAULT_PASSWORD, salt, Constants.HASH_TIME);
        user.setPassword(password);
        int result = userMapper.resetUser(user);
        if (result != 1) {
            throw new ServiceException(ServiceCode.ERR_SAVE_FAILED, "重置密码失败");
        }
    }

    @Override
    public PageVO<List<UserShowVO>> showUserList(UserPageDTO userPageDTO) {
        List<User> userList = userMapper.showUserList(userPageDTO);
        if (userList == null) {
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, "没有用户信息");
        }
        //封装查询的用户信息
        List<UserShowVO> userShowVOList = new ArrayList<>();
        userList.forEach(user -> {
            UserShowVO userShowVO = new UserShowVO();
            userShowVO.setUsername(user.getUsername());
            System.out.println(user.getUsername() + user.getCreatedTime());
            userShowVO.setCreatedTime(user.getCreatedTime());
            userShowVO.setIsDelete(user.getIsDelete());
            userShowVO.setId(user.getId());
            userShowVOList.add(userShowVO);
        });
        int count = userMapper.count();
        System.out.println("count:" + count);
        PageVO<List<UserShowVO>> pageVO = new PageVO<>(userPageDTO.getPageIndex(), userPageDTO.getPageSize(), count, userShowVOList);
        return pageVO;
    }

    @Override
    public PageVO<List<UserShowVO>> showUserByNameList(String username, UserPageDTO userPageDTO) {
        List<User> userList = userMapper.showUserByNameList(username, userPageDTO);
        if (userList == null) {
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, "没有用户信息");
        }
        //封装查询的用户信息
        List<UserShowVO> userShowVOList = new ArrayList<>();
        userList.forEach(user -> {
            UserShowVO userShowVO = new UserShowVO();
            userShowVO.setUsername(user.getUsername());
            userShowVO.setCreatedTime(user.getCreatedTime());
            userShowVO.setIsDelete(user.getIsDelete());
            userShowVO.setId(user.getId());
            userShowVOList.add(userShowVO);
        });
        int count = userMapper.countByName(username);
        if (count == 0) {
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, "没有符合的用户信息");
        }
        PageVO<List<UserShowVO>> pageVO = new PageVO<>(userPageDTO.getPageIndex(), userPageDTO.getPageSize(), count, userShowVOList);
        return pageVO;
    }


}


